package com.ma.lucenedemo.util;

import com.ma.lucenedemo.dto.Result;
import com.ma.lucenedemo.pojo.Car;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class LuceneUtil {
    /*
    * 根据数据库数据建立索引库
    * */
    public static void createIndexDataBase(List<Car> cars) throws IOException {
        //1、采集数据
        //2、创建Document对象
        ArrayList<Document> documents = new ArrayList<>();
        for (Car car : cars) {
            Document document = new Document();
            // Document文档中添加Field域
            // 汽车名称
            // Store.YES:表示存储到文档域中
            document.add(new TextField("carName", car.getBName(), Field.Store.YES));
            // 把Document放到list中
            documents.add(document);

            // 3. 创建Analyzer分词器,分析文档，对文档进行分词
//            Analyzer analyzer = new StandardAnalyzer();
            IKAnalyzer analyzer = new IKAnalyzer();
            // 4. 创建Directory对象,声明索引库的位置
            Directory directory = FSDirectory.open(Paths.get("/root/matengfei/demo/database/car"));
            // 5. 创建IndexWriteConfig对象，写入索引需要的配置
            IndexWriterConfig config = new IndexWriterConfig(analyzer);
            // 6.创建IndexWriter写入对象
            IndexWriter indexWriter = new IndexWriter(directory, config);
            // 7.写入到索引库，通过IndexWriter添加文档对象document
            for (Document doc : documents) {
                indexWriter.addDocument(doc);
            }
            // 8.释放资源
            indexWriter.close();
        }
    }

    /*
    * 根据关键字查找相对于的车辆名称
    * 对用户输入的关键字进行分词解析（完成搜索栏功能）
    */
    public static String parseKey(String keyWord) throws IOException, ParseException {
        // 1. 创建Query搜索对象
        // 创建分词器
//        Analyzer analyzer = new StandardAnalyzer();
        IKAnalyzer analyzer = new IKAnalyzer();
        // 创建搜索解析器，第一个参数：默认Field域，第二个参数：分词器
        QueryParser queryParser = new QueryParser("carName", analyzer);

        // 创建搜索对象
        Query query = queryParser.parse(keyWord);

        // 2. 创建Directory流对象,声明索引库位置
        Directory directory = FSDirectory.open(Paths.get("/root/matengfei/demo/database/car"));
        // 3. 创建索引读取对象IndexReader
        IndexReader reader = DirectoryReader.open(directory);
        // 4. 创建索引搜索对象
        IndexSearcher searcher = new IndexSearcher(reader);
        // 5. 使用索引搜索对象，执行搜索，返回结果集TopDocs
        // 第一个参数：搜索对象，第二个参数：返回的数据条数，指定查询结果最顶部的n条数据返回
        TopDocs topDocs = searcher.search(query, 1);
        System.out.println("查询到的数据总条数是：" + topDocs.totalHits);
        // 获取查询结果集
        ScoreDoc[] docs = topDocs.scoreDocs;
        String result = null;
        // 6. 解析结果集
        for (ScoreDoc scoreDoc : docs) {
            // 获取文档
            int docID = scoreDoc.doc;
            Document doc = searcher.doc(docID);
            System.out.println("=============================");
            System.out.println("id:" + docID);
            System.out.println("carName:" + doc.get("carName"));
            result = doc.get("carName");
        }
        reader.close();
        return result;
    }


    /*
    * 批量关键字查询
    * */
    public static List<Result> parseManyKey(List<String> list) throws ParseException, IOException {
        // 1. 创建Query搜索对象
        // 创建分词器
//        Analyzer analyzer = new StandardAnalyzer();
        IKAnalyzer analyzer = new IKAnalyzer();
        // 创建搜索解析器，第一个参数：默认Field域，第二个参数：分词器
        QueryParser queryParser = new QueryParser("carName", analyzer);

        // 2. 创建Directory流对象,声明索引库位置
        Directory directory = FSDirectory.open(Paths.get("/root/matengfei/demo/database/car"));
        // 3. 创建索引读取对象IndexReader
        IndexReader reader = DirectoryReader.open(directory);
        // 4. 创建索引搜索对象
        IndexSearcher searcher = new IndexSearcher(reader);

        //创建搜索对象
        // 5. 使用索引搜索对象，执行搜索，返回结果集TopDocs
        // 第一个参数：搜索对象，第二个参数：返回的数据条数，指定查询结果最顶部的n条数据返回
        //封装数据，便于写excel
        List<String> strings = new ArrayList<>();
        Query query = null;
        for (String s : list) {
            System.out.println("输出结果=====>"+s);
            query = queryParser.parse(QueryParser.escape(s));
            TopDocs docs = searcher.search(query, 1);
            ScoreDoc[] scoreDocs = docs.scoreDocs;
            int docId = scoreDocs[0].doc;
            String carName = searcher.doc(docId).get("carName");
            strings.add(carName);
//            for (ScoreDoc scoreDoc : scoreDocs) {
//                int docId = scoreDoc.doc;
//                Document doc = searcher.doc(docId);
//                String carName = doc.get("carName");
//                strings.add(carName);
//            }
        }

        List<Result> results = new ArrayList<>();
        Result result = null;
        for (int i = 0; i < list.size(); i++) {
            result = new Result();
            result.setAName(list.get(i));
            result.setBName(strings.get(i));
            results.add(result);
        }
        return results;
    }
}
